package com.aaa.vegetablemarketexpress.controller;

import com.aaa.vegetablemarketexpress.dao.UserDao;
import com.aaa.vegetablemarketexpress.entity.Contact;
import com.aaa.vegetablemarketexpress.entity.LoginLog;
import com.aaa.vegetablemarketexpress.entity.User;
import com.aaa.vegetablemarketexpress.service.ContactService;
import com.aaa.vegetablemarketexpress.service.LoginLogService;
import com.aaa.vegetablemarketexpress.service.UserService;
import com.aaa.vegetablemarketexpress.util.*;
import com.aaa.vegetablemarketexpress.vo.UserStatisticsVO;
import com.github.pagehelper.PageInfo;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.crypto.hash.Sha512Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;

/**
 * @FileName: UserController
 * @Description:
 * @Author: qxh
 * @CreateTime: 2025/9/6 15:33
 * @Version: 1.0.0
 */
@RestController
@RequestMapping("user")
@Log4j2
public class UserController {
    // 从配置文件注入头像存储路径和访问前缀
   /* @Value("${file.upload.avatar-path}")
    private String avatarSavePath;
    @Value("${file.access.prefix}")
    private String fileAccessPrefix;*/
    @Resource
    private UserService userService;
    @Resource
    private LoginLogService loginLogService;// 登录日志服务
@Resource
private ContactService contactService;
    @Autowired
    private UserDao userDao;

    /**
     * 检查用户登录状态
     * @param session
     * @return
     */
    @GetMapping("/checkLoginStatus")
    public Result checkLoginStatus(HttpSession session) {
        User userInfo = (User) session.getAttribute("userInfo");
        if (userInfo != null) {
            return ResultUtil.success(userInfo);
        } else {
            return ResultUtil.failed("用户未登录");
        }
    }
    /**
     * 用户登录
     * @param userName
     * @param password
     * @return
     */
//    @GetMapping("login")
//    public Result login(String userName, String password) {
//        log.info("用户登录");
//        return userService.login(userName, password);
//    }
    @GetMapping("login")
    public Result login(String userName, String password, HttpServletRequest request, HttpSession session) {
        log.info("用户登录");

        // 创建登录日志对象
        LoginLog loginLog = new LoginLog();
        loginLog.setUserName(userName);
        loginLog.setIpaddr(getClientIP(request));
        loginLog.setLoginLocation("未知"); // 可以通过IP地址解析位置
        loginLog.setBrowser(getBrowserName(request));
        loginLog.setOs(getOsName(request));

        try {
            //Result result = userService.login(userName, password);
            Result result = userService.checkUser(userName, password);
            if (result.getCode() == 200) {
                loginLog.setStatus("0"); // 成功
                loginLog.setMsg("登录成功");
                // 正确设置session中的用户信息
                session.setAttribute("userInfo", result.getData());
            } else {
                loginLog.setStatus("1"); // 失败
                loginLog.setMsg(result.getMessage()); // 修复：使用getMsg()而不是getMessage()
            }
            // 记录登录日志
            loginLogService.insertLoginLog(loginLog);
            return result;
        } catch (Exception e) {
            loginLog.setStatus("1"); // 失败
            loginLog.setMsg("登录异常: " + e.getMessage());
            loginLogService.insertLoginLog(loginLog);
            return ResultUtil.failed("登录异常: " + e.getMessage());
        }
    }



    // 获取客户端IP地址
    private String getClientIP(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    // 获取浏览器名称
    private String getBrowserName(HttpServletRequest request) {
        String header = request.getHeader("User-Agent");
        if (header == null) {
            return "未知";
        }
        if (header.contains("Chrome")) {
            return "Chrome";
        } else if (header.contains("Firefox")) {
            return "Firefox";
        } else if (header.contains("Safari")) {
            return "Safari";
        } else if (header.contains("Edge")) {
            return "Edge";
        } else {
            return "未知";
        }
    }

    // 获取操作系统名称
    private String getOsName(HttpServletRequest request) {
        String header = request.getHeader("User-Agent");
        if (header == null) {
            return "未知";
        }
        if (header.contains("Windows")) {
            return "Windows";
        } else if (header.contains("Mac")) {
            return "Mac";
        } else if (header.contains("Linux")) {
            return "Linux";
        } else {
            return "未知";
        }
    }
    /**
     * 用户登出
     * @return
     */
    @GetMapping("logout")
    public Result logout(HttpSession  session) {
        log.info("用户登出");
        session.removeAttribute("userInfo");
        session.invalidate();
        return ResultUtil.success("登出成功");
    }
    /**
     * 查询用户信息
     * @param userId
     * @return
     */
    @PostMapping("selectUserById")
    public Result selectUserById(Long userId) {
        log.info("查询用户信息");
        return ResultUtil.success(userService.selectUserById(userId));
    }
    /**
     * 查询用户列表
     * @param page
     * @return
     */
    @PostMapping("selectUserList")
    public Result selectUserList(@RequestBody Page<User> page) {
        log.info("查询用户列表");
        return ResultUtil.success(userService.selectUserList(page));
    }
    /**
     *  添加用户
     * @param user
     * @return
     */
    @PostMapping("insertUser")
    public Result insertUser(@RequestBody User user) {
        log.info("添加用户");
        return ResultUtil.success(userService.insertUser(user));
    }
    /**
     * 修改用户
     * @param user
     * @return
     */
    @PostMapping("updateUser")
    public Result updateUser(@RequestBody User user) {
        log.info("修改用户");
        return ResultUtil.success(userService.updateUser(user));
    }
    /**
     * 删除用户
     * @param userId
     * @return
     */
    @DeleteMapping("deleteUserById")
    public Result deleteUserById(Long userId) {
        log.info("删除用户");
        return ResultUtil.success(userService.deleteUserById(userId));
    }
    /**
     * 根据用户ID查询用户详细信息（包含角色信息）
     * @param userId
     * @return
     */
    @GetMapping("/getUserWithRoles/{userId}")
    public Result getUserWithRoles(@PathVariable("userId") Long userId) {
        log.info("开始查询用户详细信息，用户ID: {}", userId);
        User user = userService.selectUserByIdWithRoles(userId);
        if (user == null) {
            log.warn("未找到ID为{}的用户信息", userId);
            return ResultUtil.failed("未找到对应的用户信息");
        }
        log.info("查询用户详细信息结束");
        return ResultUtil.success(user);
    }
    /**
     * 为用户授权角色
     * @param user
     * @return
     */
    @PostMapping("/authRole")
    public Result authRole(@RequestBody User user) {
        log.info("开始为用户授权角色，用户ID: {}", user.getUserId());
        if (user.getUserId() == null) {
            return ResultUtil.failed("用户ID不能为空");
        }
        try {
            Long[] roleIds = null;
            if (user.getRoleIds() != null) {
                roleIds = user.getRoleIds().toArray(new Long[0]);
            }
            int result = userService.insertUserAuth(user.getUserId(), roleIds);
            if (result > 0) {
                log.info("用户授权角色成功，用户ID: {}", user.getUserId());
                return ResultUtil.success("用户授权角色成功");
            } else {
                log.warn("用户授权角色失败");
                return ResultUtil.failed("用户授权角色失败");
            }
        } catch (Exception e) {
            log.error("用户授权角色时发生异常", e);
            return ResultUtil.failed("用户授权角色失败: " + e.getMessage());
        }
    }

    /**
     *头像上传接口（本地存储）
     * @param file 前端上传的头像文件
     * @return 包含头像访问路径的Result
     */
    /*@PostMapping("/uploadAvatar")
    public Result uploadAvatar(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return ResultUtil.failed("上传文件为空");
        }

        String originalFilename = file.getOriginalFilename();
        if (!originalFilename.endsWith(".jpg") && !originalFilename.endsWith(".png")) {
            return ResultUtil.failed("仅支持 jpg/png 格式");
        }

        if (file.getSize() > 2 * 1024 * 1024) {
            return ResultUtil.failed("文件不能超过 2MB");
        }

        // 生成唯一文件名
        String fileName = UUID.randomUUID().toString() + "_" + originalFilename;

        // 获取保存路径（来自配置）
        String fullPath = avatarSavePath; // 例如：uploads/avatar/

        try {
            Path path = Paths.get(fullPath);
            if (!Files.exists(path)) {
                Files.createDirectories(path);
            }

            Path filePath = Paths.get(fullPath + fileName);
            *//*Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);*//*
            try (InputStream inputStream = file.getInputStream()) {
                Files.copy(inputStream, filePath, StandardCopyOption.REPLACE_EXISTING);
            }
            // 构造访问 URL
            String accessUrl = fileAccessPrefix + "avatar/" + fileName;

            Map<String, Object> result = new HashMap<>();
            result.put("url", accessUrl);
            result.put("fileName", fileName);

            log.info("头像上传成功，文件名：{}", fileName);

            return ResultUtil.success(result);
        } catch (Exception e) {
            log.error("头像上传失败", e);
            return ResultUtil.failed("上传失败：" + e.getMessage());
        }
    }*/


    /**
     * 生成验证码（需要验证用户身份）
     * @param session
     * @return
     */
    @GetMapping("/captcha")
    public Result getCaptcha(HttpSession session) {
        // 检查用户是否已登录
        User currentUser = (User) session.getAttribute("userInfo");
        if (currentUser == null) {
            return ResultUtil.failed("用户未登录");
        }
        
        // 生成4位随机数字验证码
        String captcha = String.valueOf(new Random().nextInt(9000) + 1000);

        // 更新用户remark字段为验证码
        currentUser.setRemark(captcha);
        // 更新更新时间
        currentUser.setUpdateTime(new Date());

        // 用服务层更新用户信息
        userService.updateUser(currentUser);

        log.info("为用户 {} 生成验证码: {}", currentUser.getUserName(), captcha);

        return ResultUtil.success("验证码已生成");
    }

    /**
     * 发送验证码（根据用户名和手机号验证后发送）
     * @param params 包含用户名和手机号的参数
     * @return
     */
    @PostMapping("/sendCaptcha")
    public Result sendCaptcha(@RequestBody Map<String, String> params, HttpSession session) {
        String userName = params.get("userName");
        String phoneNumber = params.get("phoneNumber");

        log.info("请求发送验证码，用户名: {}, 手机号: {}", userName, phoneNumber);

        // 验证用户名和手机号是否匹配
        User user = userService.selectUserByUserNameAndPhone(userName, phoneNumber);
        if (user == null) {
            return ResultUtil.failed("用户名或手机号不正确");
        }

        // 检查是否在1分钟内已发送过验证码
        String lastSendTimeStr = (String) session.getAttribute("lastCaptchaSendTime_" + user.getUserId());
        if (lastSendTimeStr != null) {
            try {
                long lastSendTime = Long.parseLong(lastSendTimeStr);
                long currentTime = System.currentTimeMillis();
                long timeDiff = currentTime - lastSendTime;

                // 1分钟内不能重复发送
                if (timeDiff < 60000) {
                    long remainingTime = (60000 - timeDiff) / 1000;
                    return ResultUtil.failed("请" + remainingTime + "秒后再尝试发送验证码");
                }
            } catch (NumberFormatException e) {
                // 如果时间格式错误，继续发送验证码
                log.warn("验证码发送时间格式错误，继续发送验证码");
            }
        }

        // 生成4位随机数字验证码
        String captcha = String.valueOf(new Random().nextInt(9000) + 1000);

        // 将验证码保存到用户remark字段中
        user.setRemark(captcha);
        user.setUpdateTime(new Date());
        userService.updateUser(user);

        // 记录发送时间到session
        session.setAttribute("lastCaptchaSendTime_" + user.getUserId(), String.valueOf(System.currentTimeMillis()));

        log.info("验证码已生成并发送至用户: {}, 验证码: {}", userName, captcha);

        // 这里应该集成短信服务发送验证码到用户手机
        // 例如: smsService.sendSms(phone, "您的验证码是: " + captcha);

        return ResultUtil.success("验证码已发送");
    }

    /**
     * 验证用户身份（忘记密码功能）
     * @param params 包含用户名、手机号和验证码的参数
     * @return
     */
    @PostMapping("verifyUser")
    public Result verifyUser(@RequestBody Map<String, String> params) {
        String userName = params.get("userName");
        String phoneNumber = params.get("phoneNumber");
        String captcha = params.get("captcha");

        log.info("验证用户身份，用户名: {}", userName);

        return userService.verifyUser(userName, phoneNumber, captcha);
    }




    /**
     *  添加管理员用户
     * @param user
     * @return
     */
    @PostMapping("registerAdmin")
    public Result registerAdmin(@RequestBody User user, String captcha, HttpSession session) {
        log.info("注册管理员用户");

        // 验证验证码
        String sessionCaptcha = (String) session.getAttribute("captcha");
        if (sessionCaptcha == null || !sessionCaptcha.equals(captcha)) {
            return ResultUtil.failed("验证码错误");
        }

        // 设置为管理员角色（假设管理员角色ID为1）
        // 这里可以根据实际需求调整角色ID
        user.setRoleIds(java.util.Arrays.asList(1L));

        try {
            User registeredUser = userService.insertUser(user);
            return ResultUtil.success( registeredUser);
        } catch (Exception e) {
            log.error("管理员注册失败", e);
            return ResultUtil.failed("注册失败: " + e.getMessage());
        }
    }

    @PostMapping("registerUser")
    public Result registerUser(@RequestBody User user,String captcha,HttpSession session) {
        log.info("注册用户");
        // 验证验证码
        String sessionCaptcha = (String) session.getAttribute("captcha");
        if (sessionCaptcha == null || !sessionCaptcha.equals(captcha)) {
            return ResultUtil.failed("验证码错误");
        }
        // 验证通过后清除验证码，防止重复使用
        session.removeAttribute("captcha");
        try {
            User registeredUser = userService.insertUser(user);
            return ResultUtil.success(registeredUser);
        } catch (Exception e) {
            log.error("用户注册失败", e);
            return ResultUtil.failed("注册失败: " + e.getMessage());
        }
    }

//    /**
//     * 验证用户身份（忘记密码功能）
//     * @param user 包含用户名和邮箱的用户对象
//     * @return
//     */
//    @PostMapping("verifyUser")
//    public Result verifyUser(@RequestBody User user, HttpSession session) {
//        log.info("验证用户身份，用户名: {}", user.getUserName());
//
//        // 获取并验证验证码
//        String captcha = user.getRemark(); // 使用remark字段临时存储验证码
//        String sessionCaptcha = (String) session.getAttribute("captcha");
//        if (sessionCaptcha == null || !sessionCaptcha.equals(captcha)) {
//            return ResultUtil.failed("验证码错误");
//        }
//
//        return userService.verifyUser(user.getUserName(), user.getEmail());
//    }

    /**
     * 重置用户密码
     * @param user 包含用户ID和新密码的用户对象
     * @return
     */
    @PostMapping("resetPassword")
    public Result resetPassword(@RequestBody User user) {
        log.info("重置用户密码，用户ID: {}", user.getUserId());
        try {
            int result = userService.resetPassword(user.getUserId(), user.getPassword());
            if (result > 0) {
                return ResultUtil.success("密码重置成功");
            } else {
                return ResultUtil.failed("密码重置失败");
            }
        } catch (Exception e) {
            log.error("密码重置失败", e);
            return ResultUtil.failed("密码重置失败: " + e.getMessage());
        }
    }
    /**
     * 上传头像
     * @param file
     * @return
     */
    @PostMapping("/uploadAvatarImage")
    public Result uploadAvatarImage(@RequestParam("pic") MultipartFile file) {
        //调用工具类，进行上传
        return ResultUtil.success(OssUtil.uploadFile("avatar/images",file));
    }
    /**
     * 获取用户统计信息
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @param deptId 部门ID
     * @return 用户统计信息
     */
    @GetMapping("/statistics")
    public Result getUserStatistics(
            @RequestParam(value = "startDate", required = false) String startDate,
            @RequestParam(value = "endDate", required = false) String endDate,
            @RequestParam(value = "deptId", required = false) Long deptId) {

        log.info("获取用户统计信息, startDate: {}, endDate: {}, deptId: {}", startDate, endDate, deptId);

        try {
            Map<String, Object> params = new HashMap<>();
            params.put("startDate", startDate);
            params.put("endDate", endDate);
            params.put("deptId", deptId);

            UserStatisticsVO statistics = userService.getUserStatistics(params);
            return ResultUtil.success(statistics);
        } catch (Exception e) {
            log.error("获取用户统计信息失败", e);
            return ResultUtil.failed("获取统计信息失败: " + e.getMessage());
        }
    }
    /**
     * 修改用户密码
     *
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     * @return 操作结果
     */
    @PostMapping("/updatePassword")
    public Result updatePassword(@RequestParam String oldPassword,
                                 @RequestParam String newPassword) {
        // 参数校验
        if (StringUtils.isEmpty(oldPassword)) {
            return ResultUtil.failed("旧密码不能为空");
        }
        if (StringUtils.isEmpty(newPassword)) {
            return ResultUtil.failed("新密码不能为空");
        }

        // 创建用户对象，用于传递旧密码
        User user = new User();
        user.setPassword(oldPassword);

        // 调用服务层方法修改密码
        return userService.updatePassword(user, newPassword);
    }
    /*@PostMapping("forgetPassword")
    public Result forgetPassword(@RequestBody User user,String captcha,HttpSession session) {
        System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        // 验证验证码
        String sessionCaptcha = (String) session.getAttribute("captcha");
        if (sessionCaptcha == null || !sessionCaptcha.equals(captcha)) {
            return ResultUtil.failed("验证码错误");
        }
        // 验证通过后清除验证码，防止重复使用
        session.removeAttribute("captcha");
        try {
            int i = userService.forgetPassword(user);
            return ResultUtil.success(i);
        } catch (Exception e) {
            log.error("重置密码失败", e);
            return ResultUtil.failed("重置密码失败: " + e.getMessage());
        }
    }*/
    @GetMapping("forgetPasswordCaptcha")
    public Result getCaptcha(String userName, String phonenumber) {
        // 1. 校验用户名和手机号是否为空
        if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(phonenumber)) {
            return ResultUtil.failed("用户名和手机号不能为空");
        }

        // 2. 校验用户是否存在（复用forgetPassword中的用户查询逻辑）
        User queryUser = new User();
        queryUser.setUserName(userName);
        queryUser.setPhonenumber(phonenumber);
        List<User> userList = userDao.selectUserList(queryUser);
        if (CollectionUtils.isEmpty(userList)) {
            return ResultUtil.failed("用户名或手机号不存在");
        }

        // 3. 生成4位数字验证码
        String captcha = String.format("%04d", new Random().nextInt(10000));
        User updateUser = new User();
        User existingUser = userList.get(0);
        updateUser.setUserId(existingUser.getUserId());
        updateUser.setRemark(captcha); // 验证码存入remark字段
        updateUser.setUpdateTime(new Date()); // 记录验证码生成时间

        // 4. 更新到数据库
        int rows = userDao.updateUser(updateUser);
        if (rows > 0) {
            return ResultUtil.success("验证码已发送至手机");
        } else {
            return ResultUtil.failed("验证码生成失败");
        }
    }
    @PostMapping("forgetPassword")
    public Result forgetPassword(@RequestBody User user, String captcha) {
        // 1. 校验用户名、手机号、验证码是否为空
        String userName = user.getUserName();
        String phonenumber = user.getPhonenumber();
        if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(phonenumber) || StringUtils.isEmpty(captcha)) {
            return ResultUtil.failed("用户名、手机号或验证码不能为空");
        }

        // 2. 查询用户（通过用户名+手机号定位唯一用户）
        User queryUser = new User();
        queryUser.setUserName(userName);
        queryUser.setPhonenumber(phonenumber);
        List<User> userList = userDao.selectUserList(queryUser);
        if (CollectionUtils.isEmpty(userList)) {
            return ResultUtil.failed("用户不存在");
        }
        User existingUser = userList.get(0);

        // 3. 校验验证码（对比remark字段中的值）
        String dbCaptcha = existingUser.getRemark();
        if (StringUtils.isEmpty(dbCaptcha) || !dbCaptcha.equals(captcha)) {
            return ResultUtil.failed("验证码错误");
        }

        // 4. 校验验证码有效期（当前时间 - 生成时间 > 60秒则失效）
        Date captchaCreateTime = existingUser.getUpdateTime();
        long timeDiff = new Date().getTime() - captchaCreateTime.getTime();
        if (timeDiff > 60 * 1000) { // 1分钟=60000毫秒
            return ResultUtil.failed("验证码已失效，请重新获取");
        }

        try {
            // 5. 重置密码（复用原加密逻辑，清空remark字段避免重复使用）
            String salt = UUID.randomUUID().toString();
            String newPassword = new Sha512Hash(user.getPassword(), salt, 1024).toString();

            User updateUser = new User();
            updateUser.setUserId(existingUser.getUserId());
            updateUser.setPassword(newPassword);
            updateUser.setSalt(salt);
            updateUser.setUpdateTime(new Date());
            updateUser.setRemark(""); // 清空验证码，防止重复使用

            int rows = userDao.updateUser(updateUser);
            return ResultUtil.success( "密码重置成功");
        } catch (Exception e) {
            log.error("重置密码失败", e);
            return ResultUtil.failed("重置密码失败: " + e.getMessage());
        }
    }
    /**
     * 生成验证码
     * @param session
     * @return
     */
    @GetMapping("/registerCaptcha")
    public Result registerCaptcha(HttpSession session) {
        // 生成4位随机数字验证码
        String captcha = String.valueOf(new Random().nextInt(9000) + 1000);
        session.setAttribute("captcha", captcha);
        log.info("生成验证码: {}", captcha);
        return ResultUtil.success(captcha);
    }

}
